package com.codi.bus.core.service.impl;

import com.codi.base.exception.BaseAppException;
import com.codi.bus.core.dao.FundOptionalDao;
import com.codi.bus.core.dao.FundOptionalPortfolioDao;
import com.codi.bus.core.domain.FundCombination;
import com.codi.bus.core.domain.FundOptional;
import com.codi.bus.core.domain.FundOptionalPortfolio;
import com.codi.bus.core.resultModel.*;
import com.codi.bus.core.service.FundCombinationService;
import com.codi.bus.core.service.FundDetailService;
import com.codi.bus.core.service.OptionalService;
import com.codi.bus.core.service.model.OptionalCurrencyModel;
import com.codi.bus.core.service.model.OptionalFundModel;
import com.codi.bus.core.service.model.OptionalPortfolioModel;
import com.codi.bus.core.vo.OptionalFundVo;
import com.google.common.base.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by asus on 2017/12/6.
 */
@Service("optionalService")
@Transactional
public class OptionalServiceImpl implements OptionalService {
    @Autowired
    private FundOptionalDao fundOptionalDao;

    @Autowired
    private FundOptionalPortfolioDao fundOptionalPortfolioDao;

    @Autowired
    private FundCombinationService fundCombinationService;

    @Autowired
    private FundDetailService fundDetailService;

    @Override
    public BaseResult addPortfolio(String portfolioCode, String portfolioName, Long userId) {
        if (Strings.isNullOrEmpty(portfolioCode)) {
            return new BaseResult(false);
        }
        FundOptionalPortfolio fundOptionalPortfolio = new FundOptionalPortfolio();
        fundOptionalPortfolio.setCreateDate(new Date());
        fundOptionalPortfolio.setLastUpdatedDate(new Date());
        fundOptionalPortfolio.setUserId(userId);
        fundOptionalPortfolio.setPortfolioCode(portfolioCode);
        fundOptionalPortfolio.setPortfolioName(portfolioName);
        List<FundOptionalPortfolio> fundOptionalPortfolios = fundOptionalPortfolioDao.selectByUserId(userId);
        if (fundOptionalPortfolios.size() == 0) {
            fundOptionalPortfolio.setFundOrder(1L);
        } else {
            fundOptionalPortfolio.setFundOrder(fundOptionalPortfolios.get(fundOptionalPortfolios.size() - 1).getFundOrder() + 1);
        }
        for (FundOptionalPortfolio fundOptionalPortfolioExist : fundOptionalPortfolios) {
            if (fundOptionalPortfolioExist.getUserId().equals(fundOptionalPortfolio.getUserId()) && fundOptionalPortfolioExist.getPortfolioCode().equals(fundOptionalPortfolio.getPortfolioCode())) {
                return new BaseResult();
            }
        }
        fundOptionalPortfolioDao.insert(fundOptionalPortfolio);
        return new BaseResult();
    }

    @Override
    public BaseResult addFund(OptionalFundVo fundOptionalVo, Long userId) throws BaseAppException {
        if (Strings.isNullOrEmpty(fundOptionalVo.getFundCode()) || Strings.isNullOrEmpty(fundOptionalVo.getFundTypeName())) {
            return new BaseResult(false);
        }
        FundOptional fundOptional = new FundOptional();
        fundOptional.setCreateDate(new Date());
        fundOptional.setLastUpdatedDate(new Date());
        fundOptional.setUserId(userId);
        fundOptional.setFundCode(fundOptionalVo.getFundCode());
        fundOptional.setFundTypeName(fundOptionalVo.getFundTypeName());
        fundOptional.setFundName(fundOptionalVo.getFundName());
        fundOptional.setFundTypeCode(fundOptionalVo.getFundTypeCode());
        FundDetailResult fundDetailResult = fundDetailService.getFundValueByFundCode(fundOptionalVo.getFundCode());
        fundOptional.setNvDailyGrowthRate(fundDetailResult.getNvDailyGrowthRate());
        fundOptional.setUnitnv(fundDetailResult.getUnitNV());
        fundOptional.setTradingDay(fundDetailResult.getTradingDay());
        List<FundOptional> fundOptionals = fundOptionalDao.selectFund(userId);
        if (fundOptionals.size() == 0) {
            fundOptional.setFundOrder(1L);
        } else {
            fundOptional.setFundOrder(fundOptionals.get(fundOptionals.size() - 1).getFundOrder() + 1);
        }
        for (FundOptional fundOptionalExist : fundOptionals) {
            if (fundOptionalExist.getUserId().equals(fundOptional.getUserId()) && fundOptionalExist.getFundCode().equals(fundOptional.getFundCode())) {
                return new BaseResult();
            }
        }
        fundOptionalDao.insert(fundOptional);
        return new BaseResult();
    }

    @Override
    public BaseResult addCurrency(OptionalFundVo fundOptionalVo, Long userId) throws BaseAppException {
        if (Strings.isNullOrEmpty(fundOptionalVo.getFundCode()) || Strings.isNullOrEmpty(fundOptionalVo.getFundTypeName())) {
            return new BaseResult(false);
        }
        FundOptional fundOptional = new FundOptional();
        fundOptional.setCreateDate(new Date());
        fundOptional.setLastUpdatedDate(new Date());
        fundOptional.setUserId(userId);
        fundOptional.setFundCode(fundOptionalVo.getFundCode());
        fundOptional.setFundTypeName(fundOptionalVo.getFundTypeName());
        fundOptional.setFundName(fundOptionalVo.getFundName());
        fundOptional.setFundTypeCode(fundOptionalVo.getFundTypeCode());
        FundDetailResult fundDetailResult = fundDetailService.getFundValueByFundCode(fundOptionalVo.getFundCode());
        fundOptional.setDailyProfit(fundDetailResult.getDailyProfit());
        fundOptional.setTradingDay(fundDetailResult.getTradingDay());
        fundOptional.setLatestWeeklyYield(fundDetailResult.getLatestWeeklyYield());
        List<FundOptional> fundOptionals = fundOptionalDao.selectCurrency(userId);
        if (fundOptionals.size() == 0) {
            fundOptional.setFundOrder(1L);
        } else {
            fundOptional.setFundOrder(fundOptionals.get(fundOptionals.size() - 1).getFundOrder() + 1);
        }
        for (FundOptional fundOptionalExist : fundOptionals) {
            if (fundOptionalExist.getUserId().equals(fundOptional.getUserId()) && fundOptionalExist.getFundCode().equals(fundOptional.getFundCode())) {
                return new BaseResult();
            }
        }
        fundOptionalDao.insert(fundOptional);
        return new BaseResult();
    }

    @Override
    public BaseResult queryPortfolio(Long userId) {
        List<FundOptionalPortfolio> fundOptionalPortfolios = fundOptionalPortfolioDao.selectByUserId(userId);
        OptionalPortfolioResult result = new OptionalPortfolioResult();
        List<OptionalPortfolioModel> optionalPortfolioModels = new ArrayList<>();
        if (fundOptionalPortfolios.size() != 0) {
            for (FundOptionalPortfolio fundOptionalPortfolio : fundOptionalPortfolios) {
                OptionalPortfolioModel optionalPortfolioModel = new OptionalPortfolioModel();
                optionalPortfolioModel.setId(fundOptionalPortfolio.getId());
                optionalPortfolioModel.setPortfolioCode(fundOptionalPortfolio.getPortfolioCode());
                optionalPortfolioModel.setPortfolioName(fundOptionalPortfolio.getPortfolioName());
                optionalPortfolioModel.setFundOrder(fundOptionalPortfolio.getFundOrder());
                optionalPortfolioModel.setUserId(fundOptionalPortfolio.getUserId());
                FundCombination fundCombination = fundCombinationService.queryOne(fundOptionalPortfolio.getPortfolioCode());
                if (fundCombination != null) {
                    if(fundCombination.getAnnualizedIncome() == null){
                        optionalPortfolioModel.setAnnualizedIncome("--");
                    }
                    if(fundCombination.getAccumulatedIncome() == null){
                        optionalPortfolioModel.setAccumulatedIncome("--");
                    }
                    optionalPortfolioModel.setAnnualizedIncome(fundCombination.getAnnualizedIncome().toString());
                    optionalPortfolioModel.setAccumulatedIncome(fundCombination.getAccumulatedIncome());
                }
                optionalPortfolioModels.add(optionalPortfolioModel);
            }
        }
        result.setOptionalPortfolios(optionalPortfolioModels);
        return result;
    }

    @Override
    public BaseResult queryFund(Long userId) {
        OptionalFundResult result = new OptionalFundResult();
        List<OptionalFundModel> optionalFunds = new ArrayList<>();
        List<FundOptional> fundOptionals = fundOptionalDao.selectFund(userId);
        for (FundOptional fundOptional : fundOptionals) {
            OptionalFundModel optionalFundModel = new OptionalFundModel();
            BeanUtils.copyProperties(fundOptional,optionalFundModel);
            optionalFundModel.setUnitNV(fundOptional.getUnitnv());
//            optionalFundModel.setId(fundOptional.getId());
//            optionalFundModel.setFundCode(fundOptional.getFundCode());
//            optionalFundModel.setFundName(fundOptional.getFundName());
//            optionalFundModel.setFundOrder(fundOptional.getFundOrder());
//            optionalFundModel.setFundTypeCode(fundOptional.getFundTypeCode());
//            optionalFundModel.setFundTypeName(fundOptional.getFundTypeName());
//            optionalFundModel.setUserId(fundOptional.getUserId());
            //FundNetValueResult fundNetValueResult = null;
            //fundNetValueResult = fundDetailService.getFundNetValue(fundOptional.getFundCode(), new Date());
            optionalFunds.add(optionalFundModel);
        }
        result.setOptionalFunds(optionalFunds);
        return result;
    }

    @Override
    public BaseResult queryCurrency(Long userId) {
        OptionalCurrencyResult result = new OptionalCurrencyResult();
        List<OptionalCurrencyModel> optionalCurrencys = new ArrayList<>();
        List<FundOptional> fundOptionals = fundOptionalDao.selectCurrency(userId);
        for (FundOptional fundOptional : fundOptionals) {
            OptionalCurrencyModel optionalCurrencyModel = new OptionalCurrencyModel();
            BeanUtils.copyProperties(fundOptional,optionalCurrencyModel);

//            optionalCurrencyModel.setId(fundOptional.getId());
//            optionalCurrencyModel.setFundCode(fundOptional.getFundCode());
//            optionalCurrencyModel.setFundName(fundOptional.getFundName());
//            optionalCurrencyModel.setFundOrder(fundOptional.getFundOrder());
//            optionalCurrencyModel.setFundTypeCode(fundOptional.getFundTypeCode());
//            optionalCurrencyModel.setFundTypeName(fundOptional.getFundTypeName());
//            optionalCurrencyModel.setUserId(fundOptional.getUserId());
//            FundNetValueResult fundNetValueResult = null;
//          fundNetValueResult = fundDetailService.getFundNetValue(fundOptional.getFundCode(), new Date());

            optionalCurrencys.add(optionalCurrencyModel);
        }
        result.setOptionalCurrencys(optionalCurrencys);
        return result;
    }

    @Override
    public BaseResult orderPortfolio(String portfolioOptional, Long userId) {
        List<FundOptionalPortfolio> fundOptionalPortfolios = fundOptionalPortfolioDao.selectByUserId(userId);
        if (Strings.isNullOrEmpty(portfolioOptional)) {
            for (FundOptionalPortfolio fundOptionalPortfolio : fundOptionalPortfolios) {
                fundOptionalPortfolioDao.deleteByPrimaryKey(fundOptionalPortfolio.getId());
            }
        } else {
            String[] optionals = portfolioOptional.split("\\|");
            for (FundOptionalPortfolio fundOptionalPortfolio : fundOptionalPortfolios) {
                for (int i = 0; i < optionals.length; i++) {
                    String[] optionaal = optionals[i].split(",");
                    if (fundOptionalPortfolio.getId() == Long.parseLong(optionaal[0].trim())) {
                        fundOptionalPortfolio.setFundOrder(Long.parseLong(optionaal[1].trim()));
                        fundOptionalPortfolio.setLastUpdatedDate(new Date());
                        fundOptionalPortfolioDao.updateByPrimaryKey(fundOptionalPortfolio);
                        fundOptionalPortfolio.setDescription("d");
                    }
                }
            }
            for (FundOptionalPortfolio fundOptionalPortfolio : fundOptionalPortfolios) {
                if (Strings.isNullOrEmpty(fundOptionalPortfolio.getDescription())) {
                    fundOptionalPortfolioDao.deleteByPrimaryKey(fundOptionalPortfolio.getId());
                }
            }
        }

        return new BaseResult();
    }

    @Override
    public BaseResult orderFund(String fundOptional, Long userId, Boolean isCurrency) {
        List<FundOptional> fundOptionals = new ArrayList<>();
        if (isCurrency) {
            fundOptionals = fundOptionalDao.selectCurrency(userId);
        } else {
            fundOptionals = fundOptionalDao.selectFund(userId);
        }
        if (Strings.isNullOrEmpty(fundOptional)) {
            for (FundOptional fundOptional1 : fundOptionals) {
                fundOptionalDao.deleteByPrimaryKey(fundOptional1.getId());
            }
        } else {
            String[] optionals = fundOptional.split("\\|");
            for (FundOptional fundOptional1 : fundOptionals) {
                for (int i = 0; i < optionals.length; i++) {
                    String[] optionaal = optionals[i].split(",");
                    if (fundOptional1.getId() == Long.parseLong(optionaal[0].trim())) {
                        fundOptional1.setFundOrder(Long.parseLong(optionaal[1].trim()));
                        fundOptional1.setLastUpdatedDate(new Date());
                        fundOptionalDao.updateByPrimaryKey(fundOptional1);
                        fundOptional1.setFlag("d");
                    }
                }
            }
            for (FundOptional fundOptional1 : fundOptionals) {
                if (Strings.isNullOrEmpty(fundOptional1.getFlag())) {
                    fundOptionalDao.deleteByPrimaryKey(fundOptional1.getId());
                }
            }
        }
        return new BaseResult();
    }

    @Override
    public BaseResult isAddPortfolio(String portfolioCode, Long userId) {
        List<FundOptionalPortfolio> fundOptionalPortfolios = fundOptionalPortfolioDao.selectByUserId(userId);
        if (fundOptionalPortfolios.size() != 0) {
            for (FundOptionalPortfolio fundOptionalPortfolio : fundOptionalPortfolios) {
                if (portfolioCode.equals(fundOptionalPortfolio.getPortfolioCode())) {
                    return new BaseResult(true).setResult(true);
                }
            }
        }
        return new BaseResult(true).setResult(false);
    }

    @Override
    public BaseResult isAddFund(String fundCode, Long userId) {
        List<FundOptional> fundOptionals = fundOptionalDao.selectByUserId(userId);
        if (fundOptionals.size() != 0) {
            for (FundOptional fundOptional : fundOptionals) {
                if (fundCode.equals(fundOptional.getFundCode())) {
                    return new BaseResult(true).setResult(true);
                }
            }
        }
        return new BaseResult(true).setResult(false);
    }

    @Override
    public BaseResult deletePortfolio(String portfolioCode, Long userId) {
        int i = fundOptionalPortfolioDao.deleteByUserIdAndCode(userId, portfolioCode);
        List<FundOptionalPortfolio> fundOptionalPortfolios = fundOptionalPortfolioDao.selectByUserId(userId);
        Long order = 1L;
        if (fundOptionalPortfolios.size() != 0) {
            for (FundOptionalPortfolio fundOptionalPortfolio : fundOptionalPortfolios) {
                if (fundOptionalPortfolio.getFundOrder() > order) {
                    fundOptionalPortfolio.setFundOrder(order);
                    fundOptionalPortfolioDao.updateByPrimaryKey(fundOptionalPortfolio);
                }
                order++;
            }
        }
        return new BaseResult(true).setResult(i);
    }

    @Override
    public BaseResult deleteFund(String fundCode, Long userId, int fundTypeCode) {
        int i = fundOptionalDao.deleteByUserIdAndCode(userId, fundCode);
        List<FundOptional> fundOptionals = new ArrayList<>();
        if (fundTypeCode == 1109){
            fundOptionals = fundOptionalDao.selectCurrency(userId);
        }else {
            fundOptionals = fundOptionalDao.selectFund(userId);
        }
        Long order = 1L;
        if (fundOptionals.size() != 0) {
            for (FundOptional fundOptional : fundOptionals) {
                if (fundOptional.getFundOrder() > order) {
                    fundOptional.setFundOrder(order);
                    fundOptionalDao.updateByPrimaryKey(fundOptional);
                }
                order++;
            }
        }
        return new BaseResult(true).setResult(i);
    }

    @Override
    public void updateFundOptional() throws BaseAppException {
        List<FundOptional> fundOptionals = fundOptionalDao.selectAll();
        for (FundOptional fundOptional :fundOptionals){
            FundDetailResult fundDetailResult = fundDetailService.getFundValueByFundCode(fundOptional.getFundCode());
            fundOptional.setLatestWeeklyYield(fundDetailResult.getLatestWeeklyYield());
            fundOptional.setDailyProfit(fundDetailResult.getDailyProfit());
            fundOptional.setTradingDay(fundDetailResult.getTradingDay());
            fundOptional.setUnitnv(fundDetailResult.getUnitNV());
            fundOptional.setNvDailyGrowthRate(fundDetailResult.getNvDailyGrowthRate());
            fundOptionalDao.updateByPrimaryKey(fundOptional);
        }
    }
}
